/*
 * 1.实现网络连接
 * 2.处理客户端请求
 */

#include<unistd.h>
#include<fcntl.h>//文件操作头文件
#include<arpa/inet.h>//网络相关头文件
#include<sys/socket.h>//socket

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//创建socked完成tcp前四步，并返回服务器fd
int initserver();

//处理客户端请求
void handclient(int fd);

int main()
{
	//1.实现连接
	int serverFd=initserver();
	//2.处理请求
	int clientfd;
	while(1)
	{
		//1.等待客户端连接
		clientfd=accept(serverFd,NULL,NULL);
		
		printf("有客户端连接服务器\n");
		//2.处理客户端请求
		handclient(clientfd);		
		//3.close
		close(clientfd);
	}
	return 0;
}

//1. 创建 sockedFd	 socket网络套接字 fd文件描述符
//	fd是个整数，可以代表网络端口
//2. 设置服务器协议簇
//	确定服务器的ip与端口号
//3. 绑定
//	将fd和协议簇绑定
//4. 监听
int initserver()
{
	//1.
	int fd=socket(AF_INET,SOCK_STREAM,0);
	if(fd == -1){
		printf("创建socket失败：");
		return -1;
	}
	printf("创建socket成功！\n");
	//2.
	struct sockaddr_in addr={0};
	addr.sin_family = AF_INET;//和socket创建时第一个参数相同
	addr.sin_port = htons(80);//所有浏览器用的都是这个端口 ，htons()将小端转为大端
	addr.sin_addr.s_addr=INADDR_ANY;//当前电脑上任意网卡都可以，
	//inet_addr("127.0.0.1");	//或者可以这样写，绑定本地回环ip
	//int_addr("192.168.232.128");	//或者本机ip
	//3.
	int r = bind(fd,(struct sockaddr*)&addr,sizeof addr);
	if(r==-1){
		perror("绑定失败：");
		close(fd);
		return -1;
	}
	printf("绑定成功!\n");
	//4.
	r = listen(fd,10);	
	if(r==-1){
		perror("监听失败：");
		close(fd);
		return -1;
	}
	printf("监听成功！\n");
	
	return fd;
}

//处理客户端请求
void handclient(int fd)
{
	//接收客户端的请求	
	char buff[1024*1024]={0};//1M
	int r=read(fd,buff,sizeof buff);
	if(r>0){
		printf("接收到客户端请求：%s\n",buff);

	//解析客户端请求
	char fileName[20]={0};
	sscanf(buff,"GET /%s",fileName);
	printf("解析出的文件名为：%s",fileName);	
	
	//根据文件名 得到文件类型，告诉服务器 发送什么文件	
	char* mime = NULL;
	if(strstr(fileName,".html")){
		mime="text/html";//文本类型或html类型	
	}else if(strstr(fileName,".jpg")){
		mime="image/jpg";//图片类型
	}

	//构建响应
	char response[1024*1024]={0};
	//首行与header
	sprintf(response,"HTTP/1.1 200 0k\r\nContent-type:%s\r\n\r\n",mime);
	
	//写入文件内容
	int responseLen=strlen(response);
	int fileFd = open(fileName,O_RDONLY);//只读打开文件
	int fileLen = read(fileFd,response+responseLen,sizeof(response)-responseLen);
	write(fd,response,responseLen+fileLen);
	close(fileFd);
	sleep(2);	
		
	
	}
}
